package tuplestore

import (
	"fmt"
	"time"
)

func NewTupleStore(config Config) *TupleStore {
	store := &TupleStore{
		segments:         make(map[string]*Segment),
		idIndex:          NewIndex(),
		mergeThreshold:   config.MergeThreshold,
		maxDeltaSize:     config.MaxDeltaSize,
		maxMergeInterval: config.MaxMergeInterval,
		metrics:          setupMetrics(),
		useCompression:   config.UseCompression,
	}

	if config.InitialSegments < 1 {
		config.InitialSegments = 1
	}
	if config.BlocksPerSegment < 1 {
		config.BlocksPerSegment = 1
	}

	for i := 0; i < config.InitialSegments; i++ {
		segmentID := fmt.Sprintf("segment-%d", i)
		store.segments[segmentID] = newSegment(segmentID, config.BlocksPerSegment, config.UseCompression)
	}

	return store
}

func newSegment(id string, blockCount int, useCompression bool) *Segment {
	segment := &Segment{
		ID:      id,
		Blocks:  make(map[string]*Block),
		created: time.Now(),
	}

	for i := 0; i < blockCount; i++ {
		blockID := fmt.Sprintf("%s-block-%d", id, i)
		segment.Blocks[blockID] = &Block{
			ID:             blockID,
			DeltaStore:     &DeltaStore{tuples: make(map[string]*Tuple)},
			MainStore:      &MainStore{},
			LastMergeTime:  time.Now(),
			useCompression: useCompression,
		}
	}

	return segment
}

func (ds *DeltaStore) AddTuple(tuple *Tuple) {
	ds.mu.Lock()
	defer ds.mu.Unlock()

	if ds.tuples == nil {
		ds.tuples = make(map[string]*Tuple)
	}
	ds.tuples[tuple.ID] = tuple

	// 添加到新增元组列表
	ds.AddedTuples = append(ds.AddedTuples, tuple)
	ds.ChangeCount++
	// 更新存储大小
	ds.size += int64(len(tuple.Data))
}

// DeleteTuple 标记元组删除
func (ds *DeltaStore) DeleteTuple(id string) {
	ds.mu.Lock()
	defer ds.mu.Unlock()

	// 先获取元组大小以便更新存储大小
	if tuple, exists := ds.tuples[id]; exists {
		ds.size -= int64(len(tuple.Data))
	}

	delete(ds.tuples, id)

	if ds.DeletedIDs == nil {
		ds.DeletedIDs = make(map[string]struct{})
	}
	ds.DeletedIDs[id] = struct{}{}
	ds.ChangeCount++
}

// UpdateTuple 更新元组
func (ds *DeltaStore) UpdateTuple(tuple *Tuple) {
	ds.mu.Lock()
	defer ds.mu.Unlock()

	// 更新存储大小：减去旧元组大小，加上新元组大小
	if oldTuple, exists := ds.tuples[tuple.ID]; exists {
		ds.size -= int64(len(oldTuple.Data))
	}

	if ds.tuples == nil {
		ds.tuples = make(map[string]*Tuple)
	}
	ds.tuples[tuple.ID] = tuple
	ds.size += int64(len(tuple.Data))

	if ds.UpdatedTuples == nil {
		ds.UpdatedTuples = make(map[string]*Tuple)
	}
	ds.UpdatedTuples[tuple.ID] = tuple
	ds.ChangeCount++
}

// Size 返回当前存储大小
func (ds *DeltaStore) Size() int64 {
	ds.mu.RLock()
	defer ds.mu.RUnlock()
	return ds.size
}

//// findTuple 在存储中查找元组
//func (ds *DeltaStore) findTuple(id string) *Tuple {
//	ds.mu.RLock()
//	defer ds.mu.RUnlock()
//	return ds.tuples[id]
//}

func (m *MainStore) Add(tuple *Tuple) {
	m.mu.Lock()
	defer m.mu.Unlock()
	if m.tuples == nil {
		m.tuples = make(map[string]*Tuple)
	}
	m.tuples[tuple.ID] = tuple
}

func (b *Block) mergeDeltaStore() {
	b.DeltaStore.mu.Lock()
	defer b.DeltaStore.mu.Unlock()

	for _, tuple := range b.DeltaStore.tuples {
		b.MainStore.Add(tuple)
	}

	b.DeltaStore.tuples = make(map[string]*Tuple)
	b.DeltaStore.ChangeCount = 0
	b.DeltaStore.size = 0
}

// 以下是测试辅助方法

// GetSegments 返回存储中的所有段（仅用于测试）
func (ts *TupleStore) GetSegments() []*Segment {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	segments := make([]*Segment, 0, len(ts.segments))
	for _, segment := range ts.segments {
		segments = append(segments, segment)
	}
	return segments
}

// GetBlocks 返回段中的所有块（仅用于测试）
func (s *Segment) GetBlocks() []*Block {
	s.mu.RLock()
	defer s.mu.RUnlock()

	blocks := make([]*Block, 0, len(s.Blocks))
	for _, block := range s.Blocks {
		blocks = append(blocks, block)
	}
	return blocks
}

// GetTotalSize 返回存储的总大小
func (ts *TupleStore) GetTotalSize() int64 {
	ts.mu.RLock()
	defer ts.mu.RUnlock()

	var totalSize int64
	for _, segment := range ts.segments {
		segment.mu.RLock()
		for _, block := range segment.Blocks {
			block.mu.RLock()

			// 如果使用压缩且有压缩数据，则只计算压缩数据大小
			if ts.useCompression && block.CompressedColumns != nil && len(block.CompressedColumns) > 0 {
				// 计算压缩列的大小
				for _, col := range block.CompressedColumns {
					if col != nil {
						// 计算压缩列的总大小：
						// 1. 编码数据大小
						totalSize += int64(len(col.EncodedData))
						// 2. 空值位图大小
						totalSize += int64(len(col.NullBitmap))
						// 3. 字典大小（如果使用字典编码）
						if col.EncodingType == EncodingDictionary && col.Dictionary != nil {
							// 估算字典大小
							for _, v := range col.Dictionary {
								switch val := v.(type) {
								case string:
									totalSize += int64(len(val))
								case []byte:
									totalSize += int64(len(val))
								default:
									totalSize += 8 // 假设其他类型平均8字节
								}
							}
						}
					}
				}
			} else {
				// 如果没有启用压缩或没有压缩数据，则计算原始数据大小
				// 计算主存储大小
				block.MainStore.mu.RLock()
				for _, tuple := range block.MainStore.tuples {
					totalSize += int64(len(tuple.Data))
				}
				block.MainStore.mu.RUnlock()

				// 计算增量存储大小
				block.DeltaStore.mu.RLock()
				totalSize += block.DeltaStore.size
				block.DeltaStore.mu.RUnlock()
			}

			block.mu.RUnlock()
		}
		segment.mu.RUnlock()
	}
	return totalSize
}
